package com.eduhzy.ttw.commonsdk.core;


import android.content.Context;

import com.alibaba.android.arouter.launcher.ARouter;
import com.blankj.utilcode.util.SPUtils;
import com.blankj.utilcode.util.StringUtils;
import com.eduhzy.ttw.commonsdk.entity.CommonData;
import com.eduhzy.ttw.commonsdk.entity.LoginData;
import com.eduhzy.ttw.commonsdk.http.CommonApi;
import com.jess.arms.integration.AppManager;
import com.jess.arms.utils.ArmsUtils;

import java.io.IOException;
import java.nio.charset.Charset;
import java.util.HashMap;
import java.util.LinkedHashMap;

import okhttp3.Interceptor;
import okhttp3.Request;
import okhttp3.Response;
import retrofit2.Call;

import static com.eduhzy.ttw.commonsdk.core.Constants.DEVICEID;
import static com.eduhzy.ttw.commonsdk.core.Constants.LOGIN_NORMAL;
import static com.eduhzy.ttw.commonsdk.core.Constants.LOGIN_THIRD_QQ;
import static com.eduhzy.ttw.commonsdk.core.Constants.LOGIN_THIRD_WX;
import static com.eduhzy.ttw.commonsdk.core.Constants.LOGIN_TYPE;
import static com.eduhzy.ttw.commonsdk.core.Constants.PASSWORD;
import static com.eduhzy.ttw.commonsdk.core.Constants.TEACHER;
import static com.eduhzy.ttw.commonsdk.core.Constants.USERNAME;


/**
 * @author xubo
 */
public class TokenInterceptor implements Interceptor {
    private static final Charset UTF8 = Charset.forName("UTF-8");
    private final Context mContext;

    @Override
    public Response intercept(Interceptor.Chain chain) throws IOException {
        Request request = chain.request();
        // try the request
        Response originalResponse = chain.proceed(request);

        /*
           通过如下的办法曲线取到请求完成的数据
           原本想通过 originalResponse.body().string()
           去取到请求完成的数据,但是一直报错,不知道是okhttp的bug还是操作不当
           然后去看了okhttp的源码,找到了这个曲线方法,取到请求完成的数据后,根据特定的判断条件去判断token过期
         */
        if (originalResponse.code() == 403) {
            try {
                // try the request

                LoginData loginData = getNewToken();
                //使用新的Token，创建新的请求
                Request newRequest = chain.request()
                        .newBuilder()
                        .header("authId", loginData.getAuthId())
                        .header("authUserId", String.valueOf(loginData.getUserId()))
                        .header("Content-Type", "application/json")
                        .header("Accept", "application/json")
                        .build();
                //重新请求
                originalResponse.body().close();
                return chain.proceed(newRequest);

//                return newResponse;
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        return originalResponse;
    }

    public TokenInterceptor(Context context) {
        this.mContext = context;
    }

    /**
     * 同步请求方式，获取最新的Token * * @return
     * // 通过一个特定的接口获取新的token，此处要用到同步的retrofit请求
     */
    private LoginData getNewToken() throws IOException {
        String deviceId = SPUtils.getInstance().getString(DEVICEID, "");
        Call<CommonData<LoginData>> call = null;
        CommonApi service = ArmsUtils.obtainAppComponentFromContext(mContext).repositoryManager().obtainRetrofitService(CommonApi.class);
        HashMap<String, Object> map = null;
        int loginType = SPUtils.getInstance().getInt(LOGIN_TYPE);
        switch (loginType) {
            case LOGIN_NORMAL:
                map = new LinkedHashMap<>();
                map.put("userName", SPUtils.getInstance().getString(USERNAME));
                map.put("password", SPUtils.getInstance().getString(PASSWORD));
                map.put("deviceId", deviceId);
                map.put("clientType", TEACHER);
                call = service.getLoginDataByCall(map);
                break;
            case LOGIN_THIRD_QQ:
                map = new LinkedHashMap<>();
                map.put("userNameType", LOGIN_THIRD_QQ);
                map.put("deviceId", deviceId);
                map.put("openid", SPUtils.getInstance().getString(Constants.OPENID));
                call = service.getThirdLoginDataByCall(map);
                break;
            case LOGIN_THIRD_WX:
                map = new LinkedHashMap<>();
                map.put("userNameType", LOGIN_THIRD_WX);
                map.put("deviceId", deviceId);
                map.put("openid", SPUtils.getInstance().getString(Constants.OPENID));
                call = service.getThirdLoginDataByCall(map);
                break;
            default:

        }
        retrofit2.Response<CommonData<LoginData>> repos = call.execute();
        CommonData<LoginData> data = repos.body();
        LoginData loginData = data.getData();
        if (data.isResult()) {

            SPUtils.getInstance().put(Constants.TOKEN, loginData.getAuthId(), SPUtils.getInstance().contains(Constants.TOKEN));
            SPUtils.getInstance().put(Constants.USERID, String.valueOf(loginData.getUserId()), SPUtils.getInstance().contains(Constants.USERID));
            SPUtils.getInstance().put(Constants.USERNICKNAME, String.valueOf(loginData.getUserNickName()), SPUtils.getInstance().contains(Constants.USERNICKNAME));
            if (!StringUtils.isTrimEmpty(loginData.getUserName()) && loginType == LOGIN_NORMAL) {
                SPUtils.getInstance().put(Constants.USERNAME, loginData.getUserName(), SPUtils.getInstance().contains(Constants.USERNAME));
            }
        } else {
            SPUtils.getInstance().put(Constants.PASSWORD, "");
            SPUtils.getInstance().put(Constants.USERID, "");
            SPUtils.getInstance().put(Constants.TOKEN, "");
            ARouter.getInstance().build(RouterHub.APP_LOGINACTIVITY).withBoolean(AppManager.IS_NOT_ADD_ACTIVITY_LIST, true).navigation();
            ArmsUtils.killAll();
        }
        return loginData;

    }
}